package com.mgsc.opengllearn.render;

import android.opengl.GLES20;
import android.opengl.Matrix;
import android.view.View;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class Square extends Shape {

    private FloatBuffer vertexBuffer;
    private ShortBuffer indexBuffer;
    private final String vertexShaderCode =
            "attribute vec4 vPosition;"+
            "uniform mat4 vMatrix;"+
            "void main() {"+
            "    gl_Position = vMatrix*vPosition;"+
            "}";
    private final String fragmentShaderCode =
            "precision mediump float;"+
            "uniform vec4 vColor;"+
            "void main() {"+
            "    gl_FragColor = vColor;"+
            "}";

    private int mProgram;

    static final int COORDS_PER_VERTEX = 3;
    static float[] triangleCoords = {
            -0.5f,0.5f,0.0f, // top left
            -0.5f,-0.5f,0.0f,//bottom left
            0.5f,-0.5f,0.0f,//bottom right
            0.5f,0.5f,0.0f // top right
    };

    static short[] index = {
            0,1,2,0,2,3
    };

    private int  mPositionHandle;
    private int mColorhandle;

    private float[] mViewMatrix = new float[16];
    private float[] mProjectMatrix = new  float[16];
    private float[] mMVPMatrix = new  float[16];

    //顶点之间的偏移量
    private final int vertexStride = COORDS_PER_VERTEX * 4;

    private  int mMatrixHandler;

    //设置颜色，一次为红，绿，蓝，透明度通道
    float[] color = {1.0f,1.0f,1.0f,1.0f};
    public Square(View mView) {
        super(mView);
        ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length*4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(triangleCoords);
        vertexBuffer.position(0);

        ByteBuffer cc = ByteBuffer.allocateDirect(index.length*2);
        cc.order(ByteOrder.nativeOrder());
        indexBuffer = cc.asShortBuffer();
        indexBuffer.put(index);
        indexBuffer.position(0);

        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderCode);
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShaderCode);

        //创建一个空的OpenglES程序
        mProgram = GLES20.glCreateProgram();
        //将顶点着色器加入到程序
        GLES20.glAttachShader(mProgram,vertexShader);
        //将片元着色器加入到程序
        GLES20.glAttachShader(mProgram,fragmentShader);
        //连接到着色器程序
        GLES20.glLinkProgram(mProgram);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        //计算宽高比
        float rotio = (float)width/height;
        //设置透视投影
        Matrix.frustumM(mProjectMatrix,0,-rotio,rotio,-1,1,3,7);
        //设置相机位置
        Matrix.setLookAtM(mViewMatrix,0,0,0,7.0f,0,0,0,0,1.0f,0);
        //计算变换矩阵
        Matrix.multiplyMM(mMVPMatrix,0,mProjectMatrix,0,mViewMatrix,0);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        //将程序加入到opengles 2.0环境
        GLES20.glUseProgram(mProgram);
        //获取变换矩阵vMatrix成员句柄
        mMatrixHandler = GLES20.glGetUniformLocation(mProgram,"vMatrix");
        //指定vMatrix的值
        GLES20.glUniformMatrix4fv(mMatrixHandler,1,false,mMVPMatrix,0);
        //获取顶点着色器的vPosition成员句柄
        mPositionHandle = GLES20.glGetAttribLocation(mProgram,"vPosition");
        //启用三角形顶点的句柄
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        //准备三角形的坐标数据
        GLES20.glVertexAttribPointer(mPositionHandle,COORDS_PER_VERTEX,GLES20.GL_FLOAT,false,vertexStride,vertexBuffer);;
        //获取片元着色器的vColor成员句柄
        mColorhandle = GLES20.glGetUniformLocation(mProgram,"vColor");
        //设置绘制三角形的颜色
        GLES20.glUniform4fv(mColorhandle,1,color,0);
        //索引法绘制正方形
        GLES20.glDrawElements(GLES20.GL_TRIANGLES,index.length,GLES20.GL_UNSIGNED_SHORT,indexBuffer);
        //极致顶点数组的句柄
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
}
